﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FrontEnd
{
	#region ENUMS

	public enum FileSelectorState
	{
		NotSet,
		Valid,
		Invalid
	}

	#endregion

	public partial class SelectFileTextBox : UserControl
	{
		#region EVENTS

		public event EventHandler<FileValidatingEventArgs> FileValidating; // do extra checks on validity of file
		public event EventHandler<string> FileValidated;

		#endregion

		#region PROPERTIES

		public static readonly DependencyProperty PathProperty = DependencyProperty.Register("Path", typeof(string), typeof(SelectFileTextBox), new PropertyMetadata(string.Empty));
		public string Path
		{
			get { return (string)GetValue(PathProperty); }
			set { SetValue(PathProperty, value); }
		}

		public static readonly DependencyProperty FilterProperty = DependencyProperty.Register("Filter", typeof(string), typeof(SelectFileTextBox), new PropertyMetadata("All Files (*.*)|*.*"));
		public string Filter
		{
			get { return (string)GetValue(FilterProperty); }
			set { SetValue(FilterProperty, value); }
		}

		private static readonly DependencyPropertyKey StatePropertyKey = DependencyProperty.RegisterReadOnly("State", typeof(FileSelectorState), typeof(SelectFileTextBox), new FrameworkPropertyMetadata(FileSelectorState.NotSet));
		public static readonly DependencyProperty StateProperty = StatePropertyKey.DependencyProperty;
		public FileSelectorState State
		{
			get { return (FileSelectorState)GetValue(StateProperty); }
			private set { SetValue(StatePropertyKey, value); }
		}

		#endregion

		#region CONSTRUCTOR(S)

		public SelectFileTextBox()
		{
			InitializeComponent();
			DataContext = this;
		}

		#endregion

		#region PUBLIC METHODS

		#endregion

		#region PRIVATE METHODS

		private void btnOpen_Click(object sender, RoutedEventArgs e)
		{
			var dlg = new OpenFileDialog() { Filter = this.Filter };
			var result = dlg.ShowDialog();
			if (result == true)
			{
				this.Path = dlg.FileName;
				OnFileValidating(this.Path);

				// preview data
				if(this.State == FileSelectorState.Valid)
				{
					OnFileValidated(this.Path);
				}
			}
		}

		/// <summary>
		/// Cycles through subscribers allowing each one to check and validate the file selected
		/// </summary>
		/// <param name="filePath">The path of the file selected</param>
		private void OnFileValidating(string filePath)
		{
			bool subscriberCancelled = false;
			if (FileValidating != null)
			{
				var args = new FileValidatingEventArgs(filePath);
				foreach (EventHandler<FileValidatingEventArgs> del in FileValidating.GetInvocationList())
				{
					del(this, args);
					if (args.Cancel)
					{
						subscriberCancelled = true;
						break;
					}
				}
			}

			this.State = subscriberCancelled ? FileSelectorState.Invalid : FileSelectorState.Valid;
		}

		private void OnFileValidated(string filePath)
		{
			if (FileValidated != null)
			{
				FileValidated(this, filePath);
			}
		}

		#endregion

		#region PRIVATE MEMBERS

		#endregion
	}

	public class FileValidatingEventArgs : CancelEventArgs
	{
		public string Path { get; private set; }

		public FileValidatingEventArgs(string filePath)
		{
			this.Path = filePath;
		}
	}
}
